<!DOCTYPE html>
<html>
<head>
  <title>身份证信息识别</title>
  <meta charset="utf-8"/>
  <style>
    body {
      font-family: 'Microsoft YaHei', sans-serif;
      background-color: #f5f5f5;
      color: #333;
      margin: 0;
      padding: 0;
    }
    .container {
      max-width: 800px;
      margin: 30px auto;
      padding: 20px;
      background: white;
      border-radius: 8px;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
      position: relative;
    }
    h1 {
      text-align: center;
      color: #2c3e50;
      margin-bottom: 30px;
    }
    .upload-section {
      display: flex;
      gap: 20px;
      margin-bottom: 20px;
    }
    .upload-area {
      flex: 1;
      border: 2px dashed #3498db;
      border-radius: 5px;
      padding: 20px;
      text-align: center;
      cursor: pointer;
      transition: all 0.3s;
      min-height: 150px;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
    }
    .upload-area:hover {
      background-color: #f0f8ff;
      border-color: #2980b9;
    }
    .upload-area.active {
      background-color: #e1f0fa;
      border-color: #2980b9;
    }
    .preview-container {
      display: flex;
      gap: 20px;
      margin-bottom: 20px;
    }
    .image-preview {
      flex: 1;
      max-width: 100%;
      max-height: 200px;
      display: none;
      border: 1px solid #ddd;
      border-radius: 4px;
    }
    .file-input {
      display: none;
    }
    button {
      background-color: #3498db;
      color: white;
      border: none;
      padding: 10px 20px;
      border-radius: 5px;
      cursor: pointer;
      font-size: 16px;
      transition: background-color 0.3s;
    }
    button:hover {
      background-color: #2980b9;
    }
    button:disabled {
      background-color: #95a5a6;
      cursor: not-allowed;
    }
    .result-container {
      margin-top: 30px;
      padding: 20px;
      border: 1px solid #ddd;
      border-radius: 5px;
      background-color: #f9f9f9;
    }
    .result-title {
      font-weight: bold;
      margin-bottom: 10px;
      color: #2c3e50;
    }
    .result-grid {
      display: grid;
      grid-template-columns: 120px 1fr;
      gap: 10px;
    }
    .result-label {
      font-weight: bold;
      color: #7f8c8d;
      align-self: center;
    }
    .result-value {
      padding: 8px;
      border: 1px solid #ddd;
      border-radius: 4px;
      background-color: white;
    }
    .result-value:focus {
      outline: none;
      border-color: #3498db;
      box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
    }
    .loading {
      text-align: center;
      padding: 20px;
    }
    .spinner {
      border: 4px solid rgba(0, 0, 0, 0.1);
      width: 36px;
      height: 36px;
      border-radius: 50%;
      border-left-color: #3498db;
      animation: spin 1s linear infinite;
      margin: 0 auto 10px;
    }
    @keyframes spin {
      0% { transform: rotate(0deg); }
      100% { transform: rotate(360deg); }
    }
    .tips {
      font-size: 14px;
      color: #7f8c8d;
      margin-top: 20px;
      padding: 10px;
      background-color: #ecf0f1;
      border-radius: 5px;
    }
    .error-message {
      color: #e74c3c;
      margin-top: 20px;
      padding: 10px;
      background-color: #fadbd8;
      border-radius: 5px;
      text-align: center;
    }
    .action-buttons {
      display: flex;
      justify-content: space-between;
      margin-top: 20px;
    }
    .upload-icon {
      width: 48px;
      height: 48px;
      margin-bottom: 10px;
    }
    .upload-text {
      margin: 5px 0;
    }
    .empty-value {
      color: #95a5a6;
      font-style: italic;
    }
    .top-right-menu {
      position: absolute;
      top: 20px;
      right: 20px;
      display: flex;
      gap: 10px;
    }
    .top-right-menu a {
      background-color: #2ecc71;
      color: white;
      text-decoration: none;
      padding: 8px 15px;
      border-radius: 5px;
      font-size: 14px;
      transition: background-color 0.3s;
    }
    .top-right-menu a:hover {
      background-color: #27ae60;
    }
  </style>
</head>
<body>
<div class="container">
  <!-- 右上角功能菜单 - 添加返回首页按钮 -->
  <div class="top-right-menu">
    <a href="index.html">返回首页</a>
  </div>

  <h1>身份证信息识别</h1>

  <div class="upload-section">
    <div class="upload-area" id="frontUploadArea">
      <svg class="upload-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#3498db" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
        <polyline points="17 8 12 3 7 8"></polyline>
        <line x1="12" y1="3" x2="12" y2="15"></line>
      </svg>
      <p class="upload-text">点击上传身份证正面</p>
      <p class="upload-text"><small>支持JPG、PNG格式（不超过5MB）</small></p>
      <input type="file" class="file-input" id="frontInput" accept=".png, .jpg, .jpeg, image/png, image/jpeg">
    </div>

    <div class="upload-area" id="backUploadArea">
      <svg class="upload-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#3498db" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
        <polyline points="17 8 12 3 7 8"></polyline>
        <line x1="12" y1="3" x2="12" y2="15"></line>
      </svg>
      <p class="upload-text">点击上传身份证反面</p>
      <p class="upload-text"><small>支持JPG、PNG格式（不超过5MB）</small></p>
      <input type="file" class="file-input" id="backInput" accept=".png, .jpg, .jpeg, image/png, image/jpeg">
    </div>
  </div>

  <div class="preview-container">
    <img id="frontPreview" class="image-preview" alt="身份证正面预览">
    <img id="backPreview" class="image-preview" alt="身份证反面预览">
  </div>

  <div style="text-align: center;">
    <button id="recognizeBtn" disabled>识别身份证信息</button>
  </div>

  <div class="tips">
    <p><strong>使用提示：</strong></p>
    <ul>
      <li>请分别上传身份证正反两面照片</li>
      <li>确保照片清晰可见，无反光、遮挡</li>
      <li>正面识别姓名、性别、民族、出生日期、地址和身份证号</li>
      <li>反面识别签发机关和有效期限</li>
      <li>识别结果为空时可手动输入信息</li>
      <li>为保护隐私，识别完成后请及时清除信息</li>
    </ul>
  </div>

  <div class="error-message" id="errorMessage" style="display: none;"></div>

  <div class="result-container" id="resultContainer" style="display: none;">
    <div class="result-title">识别结果</div>
    <div class="result-grid" id="resultGrid">
      <!-- 结果将在这里动态生成 -->
    </div>
    <div class="action-buttons">
      <button id="saveBtn" style="background-color: #2ecc71;">保存修改</button>
      <button id="clearBtn" style="background-color: #e74c3c;">清除信息</button>
    </div>
  </div>

  <div class="loading" id="loading" style="display: none;">
    <div class="spinner"></div>
    <p>正在识别身份证信息，请稍候...</p>
  </div>
</div>

<script>
  // 获取DOM元素
  const frontUploadArea = document.getElementById('frontUploadArea');
  const backUploadArea = document.getElementById('backUploadArea');
  const frontInput = document.getElementById('frontInput');
  const backInput = document.getElementById('backInput');
  const frontPreview = document.getElementById('frontPreview');
  const backPreview = document.getElementById('backPreview');
  const recognizeBtn = document.getElementById('recognizeBtn');
  const resultContainer = document.getElementById('resultContainer');
  const resultGrid = document.getElementById('resultGrid');
  const loading = document.getElementById('loading');
  const errorMessage = document.getElementById('errorMessage');
  const saveBtn = document.getElementById('saveBtn');
  const clearBtn = document.getElementById('clearBtn');

  // 存储已上传的文件
  let frontFile = null;
  let backFile = null;

  // 身份证字段配置
  const idCardFields = [
    { label: '姓名', field: 'name', placeholder: '请输入姓名' },
    { label: '性别', field: 'sex', placeholder: '请输入性别' },
    { label: '民族', field: 'nation', placeholder: '请输入民族' },
    { label: '出生日期', field: 'birth', placeholder: '请输入出生日期' },
    { label: '住址', field: 'address', placeholder: '请输入住址' },
    { label: '公民身份号码', field: 'number', placeholder: '请输入身份证号码' },
    { label: '签发机关', field: 'issue', placeholder: '请输入签发机关' },
    { label: '有效期限', field: 'validDate', placeholder: '请输入有效期限' }
  ];

  // 点击上传区域触发文件选择
  frontUploadArea.addEventListener('click', () => {
    frontInput.click();
  });

  backUploadArea.addEventListener('click', () => {
    backInput.click();
  });

  // 拖拽功能
  setupDragAndDrop(frontUploadArea, frontInput, (file) => {
    frontFile = file;
    previewImage(file, frontPreview);
    checkReadyToRecognize();
  });

  setupDragAndDrop(backUploadArea, backInput, (file) => {
    backFile = file;
    previewImage(file, backPreview);
    checkReadyToRecognize();
  });

  function setupDragAndDrop(uploadArea, inputElement, callback) {
    uploadArea.addEventListener('dragover', (e) => {
      e.preventDefault();
      uploadArea.classList.add('active');
    });

    uploadArea.addEventListener('dragleave', () => {
      uploadArea.classList.remove('active');
    });

    uploadArea.addEventListener('drop', (e) => {
      e.preventDefault();
      uploadArea.classList.remove('active');

      if (e.dataTransfer.files.length) {
        const file = e.dataTransfer.files[0];
        if (validateFile(file)) {
          inputElement.files = e.dataTransfer.files;
          callback(file);
        }
      }
    });
  }

  // 文件选择变化
  frontInput.addEventListener('change', () => {
    if (frontInput.files.length) {
      const file = frontInput.files[0];
      if (validateFile(file)) {
        frontFile = file;
        previewImage(file, frontPreview);
        checkReadyToRecognize();
      }
    }
  });

  backInput.addEventListener('change', () => {
    if (backInput.files.length) {
      const file = backInput.files[0];
      if (validateFile(file)) {
        backFile = file;
        previewImage(file, backPreview);
        checkReadyToRecognize();
      }
    }
  });

  // 验证文件
  function validateFile(file) {
    const validTypes = ['image/jpeg', 'image/png'];

    if (!validTypes.includes(file.type)) {
      showError('请上传JPG或PNG格式的图片');
      return false;
    }

    if (file.size > 5 * 1024 * 1024) {
      showError('文件大小超过5MB限制');
      return false;
    }

    return true;
  }

  // 预览图片
  function previewImage(file, previewElement) {
    const reader = new FileReader();
    reader.onload = (e) => {
      previewElement.src = e.target.result;
      previewElement.style.display = 'block';
    };
    reader.readAsDataURL(file);
  }

  // 检查是否准备好识别
  function checkReadyToRecognize() {
    recognizeBtn.disabled = !(frontFile && backFile);
  }

  // 显示错误信息
  function showError(message) {
    errorMessage.textContent = message;
    errorMessage.style.display = 'block';
    recognizeBtn.disabled = true;
  }

  // 隐藏错误信息
  function hideError() {
    errorMessage.style.display = 'none';
  }

  // 识别按钮点击事件
  recognizeBtn.addEventListener('click', async () => {
    if (!frontFile || !backFile) return;

    const formData = new FormData();
    formData.append('frontFile', frontFile);
    formData.append('backFile', backFile);

    // 显示加载中，隐藏结果和错误
    loading.style.display = 'block';
    resultContainer.style.display = 'none';
    hideError();

    try {
      const response = await fetch('/ocr/IDToText', {
        method: 'POST',
        body: formData
      });

      const data = await response.json();

      // 隐藏加载中
      loading.style.display = 'none';

      if (response.ok) {
        if (data.status === 'error') {
          showError(data.text || '识别失败');
        } else {
          // 显示识别结果
          if (data.text && typeof data.text === 'object') {
            displayResults(data.text);
            resultContainer.style.display = 'block';
          } else if (data.texts) {
            showError('识别到文本但未解析出身份证信息');
          } else {
            // 即使返回null也显示所有字段
            displayResults({});
          }
        }
      } else {
        showError(data.text || '识别失败: 未知错误');
      }
    } catch (error) {
      loading.style.display = 'none';
      showError('请求失败: ' + error.message);
    }
  });

  // 显示识别结果
  function displayResults(idCardData) {
    // 清空之前的结果
    resultGrid.innerHTML = '';

    // 显示所有字段，即使返回null
    idCardFields.forEach(fieldConfig => {
      const value = idCardData[fieldConfig.field] || '';
      addEditableResultItem(
              fieldConfig.label,
              value,
              fieldConfig.placeholder,
              fieldConfig.field === 'number' // 身份证号特殊处理
      );
    });

    // 如果没有识别到任何字段且不是主动显示空表单
    if (Object.keys(idCardData).length === 0 && idCardData.constructor === Object) {
      const noticeElem = document.createElement('div');
      noticeElem.colSpan = 2;
      noticeElem.textContent = '未识别到有效信息，请手动输入或重新上传清晰照片';
      noticeElem.style.gridColumn = '1 / span 2';
      noticeElem.style.textAlign = 'center';
      noticeElem.style.color = '#e74c3c';
      noticeElem.style.marginTop = '10px';
      resultGrid.appendChild(noticeElem);
    }
  }

  // 添加可编辑的结果项
  function addEditableResultItem(label, value, placeholder, isIdNumber = false) {
    const labelElem = document.createElement('div');
    labelElem.className = 'result-label';
    labelElem.textContent = label;

    const valueElem = document.createElement('input');
    valueElem.className = 'result-value';
    valueElem.type = 'text';
    valueElem.value = value || '';
    valueElem.placeholder = placeholder;
    valueElem.setAttribute('data-field', label);

    // 特殊处理身份证号格式
    if (isIdNumber && value) {
      valueElem.value = formatIdNumber(value);
    }

    // 为空时添加特殊样式
    if (!value) {
      valueElem.classList.add('empty-value');
      valueElem.value = '';
    }

    resultGrid.appendChild(labelElem);
    resultGrid.appendChild(valueElem);
  }

  // 格式化身份证号码（添加空格）
  function formatIdNumber(idNumber) {
    if (!idNumber || idNumber.length !== 18) return idNumber;
    return idNumber.substring(0, 6) + ' ' +
            idNumber.substring(6, 14) + ' ' +
            idNumber.substring(14);
  }

  // 保存按钮点击事件
  saveBtn.addEventListener('click', () => {
    const inputs = document.querySelectorAll('.result-value');
    const modifiedData = {};

    inputs.forEach(input => {
      const field = input.getAttribute('data-field');
      // 去除身份证号中的空格
      const value = field === '公民身份号码'
              ? input.value.replace(/\s+/g, '')
              : input.value;
      modifiedData[field] = value;
    });

    // 这里可以添加保存逻辑，例如发送到服务器或显示提示
    alert('修改已保存（此处为演示，实际需要添加保存逻辑）');
    console.log('修改后的数据:', modifiedData);
  });

  // 清除按钮点击事件
  clearBtn.addEventListener('click', () => {
    // 清除文件选择和预览
    frontInput.value = '';
    backInput.value = '';
    frontPreview.src = '';
    frontPreview.style.display = 'none';
    backPreview.src = '';
    backPreview.style.display = 'none';
    recognizeBtn.disabled = true;
    frontFile = null;
    backFile = null;

    // 清除结果
    resultGrid.innerHTML = '';
    resultContainer.style.display = 'none';

    // 清除错误信息
    hideError();
  });

  // 初始化时显示空表单（可选）
  // displayResults({});
</script>
</body>
</html>